#include <QImage>
#include <QPainter>
#include <QString>
#include <QFile>
#include <QByteArray>
#include <QBuffer>
#include "reimage.h"
#include "mythread.h"
#include "lib/exif.h"
#include <QDebug>

Reimage::Reimage()
{
    
}

Reimage::Reimage(const QString &filename, int width, int height)
{
    this->load(filename);
    this->set_width(width);
    this->set_height(height);
}

Reimage::Reimage(const QString &filename, const QString &filename_s, int width, int height)
{
    this->load(filename);
    filename_save = filename_s;
    this->set_width(width);
    this->set_height(height);
}


Reimage::~Reimage()
{
}

bool Reimage::load(const QString &filename) 
{
    QFile file(filename);
    image_status = false;
    if(file.open(QIODevice::ReadOnly)){
        QByteArray ba = file.readAll();
        int fsize = ba.size(); 
        const unsigned char* buf = reinterpret_cast<const unsigned char*>(ba.data());
        image_status = image.loadFromData(ba);
        if(image_status){
            //获取图片exif信息，将图片进行旋转
            easyexif::EXIFInfo result;
            int code = result.parseFrom(buf, fsize);
            unsigned short orientation;
            if(code){
                orientation = 1;
            }else{
                orientation = result.Orientation; 
            }  
            if(orientation != 1){ 
                QMatrix matrix;
                switch (orientation){
                case 6: 
                    matrix.rotate(90);
                    break;
                case 3:
                    matrix.rotate(180);
                    break;
                case 8:
                    matrix.rotate(270);
                default:
                    break;
                }
                image = image.transformed(matrix);
            }
        }
    }
    
    return image_status;
}

bool Reimage::status()
{
    return image_status;
}

void Reimage::set_width(int width) 
{
    width_save  = width;
}

void Reimage::set_height(int height)
{
    height_save = height;
}

void Reimage::set_filename_save(const QString &filename)
{
    filename_save   = filename;
}

bool Reimage::save(int quality)
{ 
    return image.save(filename_save, 0, quality);
}

void Reimage::scaled(int width, int height)
{
    image   = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
}

void Reimage::run(Reimage::Type type) 
{
    switch(type) {
    case Reimage::Type_Fill:
        this->fill();
        break;
    case Reimage::Type_Scaled:
        this->scaled();
        break;
    case Reimage::Type_Fit_Width:
        this->fit_width();
        break;
    case Reimage::Type_Fit_Height:
        this->fit_height();
        break;
    default:
        break;
    }
}

void Reimage::fill(QColor color) 
{
    if(width_save == 0) return;
    if(height_save == 0) height_save = width_save;
    QPainter    painter;
    QImage      canvas(width_save, height_save, QImage::Format_RGB32);
    canvas.fill(color);
    painter.begin(&canvas);
    float   width   = image.width();
    float   height  = image.height();
    //缩放系数
    float   factor;
    int     width_factor;
    int     height_factor;
    
    if (width_save / width > height_save / height) {
        factor          = height_save / height;
        width_factor    = width * factor;
        height_factor   = height_save;
    } else {
        factor          = width_save / width;
        width_factor    = width_save;
        height_factor   = height * factor;
    }
    
    this->scaled(width_factor, height_factor);
    
    int postion_x   = (width_save - width_factor) / 2;
    int postion_y   = (height_save - height_factor) / 2;
    painter.drawImage(postion_x, postion_y, image);
    painter.end();
    
    image   = canvas;
}

void Reimage::scaled()
{
    this->scaled(width_save, height_save);
}

void Reimage::fit_width()
{
    float width   = image.width();
    float height  = image.height();
    float aspect_ratio  = height / width;
    
    height = width_save * aspect_ratio;
    this->scaled(width_save, height);
}

void Reimage::fit_height()
{
    float width   = image.width();
    float height  = image.height();
    
    float aspect_ratio  = height / width;
    
    width = height_save / aspect_ratio;
    this->scaled(width, height_save);
}
